home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 18 / develop 18 code / OSA Sample / Sources / ListOfLongs.cp < prev    next >
Encoding:
Text File  |  1994-01-28  |  8.0 KB  |  478 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        ListOfLongs.cp
  4.  
  5.     Contains:    TListOfLongs implementation.
  6.  
  7.     Developed by:    
  8.         
  9.         Paul G Smith (commstalk hq & Full Moon Software, Inc)
  10.         
  11.         you can leave messages at (UK): 0727 844232; (US): 408 253 7199
  12.         BUT I prefer to be contacted by e-mail
  13.         AppleLink:     SMITH.PG
  14.         Internet:     SMITH.PG@applelink.apple.com
  15.         
  16.         "SimpliFace" Sample code to accompany develop article
  17.         on techniques for embedding scripts in applications.
  18.  
  19.  
  20.     Ordered and un-ordered lists of long integers
  21.  
  22. */
  23.  
  24. #include "ListOfLongs.h"
  25.  
  26. #ifndef __LIMITS__
  27. #include <Limits.h>
  28. #endif
  29.  
  30. #ifndef __ERRORS__
  31. #include <Errors.h>
  32. #endif
  33.  
  34. #ifndef __RESOURCES__
  35. #include <Resources.h>
  36. #endif
  37.  
  38. #ifndef __PACKAGES__
  39. #include <Packages.h>
  40. #endif
  41.  
  42.  
  43.  
  44.  
  45. const short kLListChunkUnit = 16;
  46. const short kLListChunkSize = kLListChunkUnit*sizeof(long);    // allocation chunk size
  47.  
  48. /*******************************************************************************
  49. ** TListOfLongs: Constructor/Destructor
  50. ********************************************************************************/
  51.  
  52. TListOfLongs::TListOfLongs()
  53. {
  54.     fNumItems = 0;
  55.     fDataHandle = NewHandle(kLListChunkSize);
  56. }
  57.  
  58.  
  59. TListOfLongs::TListOfLongs(const TListOfLongs& oldObj)
  60. {
  61.     Handle h = oldObj.fDataHandle;
  62.     HandToHand(&h);
  63.     if (h)
  64.         fDataHandle = h;
  65.     fNumItems = oldObj.fNumItems;
  66. }
  67.  
  68.  
  69. TListOfLongs::~TListOfLongs(void)
  70. {
  71.     if (fDataHandle)
  72.         DisposHandle(fDataHandle);
  73. }
  74.  
  75.  
  76. TListOfLongs& TListOfLongs::operator=(const TListOfLongs& oldObj)
  77. {
  78.     if (this != &oldObj)
  79.     {
  80.         Handle h = oldObj.fDataHandle;
  81.         HandToHand(&h);
  82.         if (h)
  83.         {
  84.             if (fDataHandle)
  85.                 DisposHandle(fDataHandle);
  86.             fDataHandle = h;
  87.         }
  88.         fNumItems = oldObj.fNumItems;
  89.     }
  90.     return *this;
  91. }
  92.  
  93.  
  94. // the business
  95.  
  96. Handle TListOfLongs::GetData(void)
  97. {
  98.     Handle     h = NULL;
  99.     long     numElems = fNumItems;
  100.     OSErr    err = 0;
  101.     
  102.     if ((numElems > 0) && fDataHandle)
  103.     {
  104.         HLock(fDataHandle);
  105.         err = PtrToHand(*fDataHandle, &h, numElems*sizeof(long));
  106.         HUnlock(fDataHandle);
  107.     }
  108.     else
  109.         h = NewHandle(0);
  110.     
  111.     return h;
  112. }
  113.  
  114.  
  115. void TListOfLongs::SetData(Handle h)
  116. {
  117.     fNumItems = 0;
  118.     
  119.     if (h)
  120.     {
  121.         long     hs = GetHandleSize(h);
  122.         long    numItems = hs / sizeof(long);
  123.         if (numItems < 0)
  124.             numItems = 0;
  125.         if (numItems)
  126.         {
  127.             Handle nh = h;
  128.             OSErr err = HandToHand(&nh);
  129.             if (!err)
  130.             {
  131.                 fNumItems = numItems;
  132.                 DisposHandle(fDataHandle);
  133.                 fDataHandle = nh;
  134.             }
  135.         }
  136.     }
  137. }
  138.  
  139.  
  140.  
  141. OSErr TListOfLongs::ExpandDataHandle(long numLongs)
  142. {
  143.     OSErr err = 0;
  144.     
  145.     if (fDataHandle)
  146.     {
  147.         long     numElems = fNumItems;
  148.         Handle    h = fDataHandle;
  149.         long    oldSize = GetHandleSize(h);
  150.         
  151.         if (((numElems+numLongs) * sizeof(long)) > oldSize)
  152.         {
  153.             long    addSize = (numLongs / kLListChunkUnit) + 1;
  154.  
  155.             SetHandleSize(h, oldSize + addSize * kLListChunkSize);
  156.             err = MemError();
  157.         }
  158.     }
  159.     else
  160.         err = nilHandleErr;
  161.     
  162.     return err;
  163. }
  164.  
  165.  
  166.  
  167. OSErr TListOfLongs::ShrinkDataHandle(long numLongs)
  168. {
  169.     return noErr;        // do nothing, for time being
  170. }
  171.  
  172.  
  173.  
  174. OSErr TListOfLongs::InsertElement(long val)
  175. {
  176.     OSErr err = noErr;
  177.     
  178.     if (!FindElement(val))    // if it's already there, do nothing
  179.     {
  180.         long     lastItem = fNumItems;    
  181.         long**     dh = (long**) fDataHandle;
  182.         
  183.         err = ExpandDataHandle(1);    // grows dh, if more room is needed
  184.             
  185.         HLock(fDataHandle);        // locks dh
  186.         
  187.         while (lastItem > 0)
  188.         {
  189.             long     lastVal = (*dh)[lastItem-1];    // because array is indexed from 0
  190.             if (lastVal > val)
  191.             {
  192.                 (*dh)[lastItem] = lastVal;
  193.                 lastItem--;
  194.             }
  195.             else
  196.                 break;    // insert here!
  197.         }
  198.         (*dh)[lastItem] = val;
  199.         fNumItems = fNumItems + 1;
  200.         
  201.         HUnlock(fDataHandle);
  202.     }
  203.     
  204.     return err;
  205. }
  206.  
  207.  
  208. void TListOfLongs::DeleteElement(long val)
  209. {
  210.     long    foundIndex = FindElement(val);
  211.     
  212.     if (foundIndex)
  213.     {
  214.         long     numElems = fNumItems;
  215.         
  216.         if ((numElems > 0) && fDataHandle)
  217.         {
  218.             long**     dh = (long**) fDataHandle;
  219.             long    currentIndex = foundIndex-1;
  220.             
  221.             HLock(fDataHandle);        // locks dh
  222.         
  223.             while (currentIndex < numElems-1)
  224.             {
  225.                 (*dh)[currentIndex] = (*dh)[currentIndex+1];
  226.                 currentIndex++;
  227.             }
  228.             fNumItems = fNumItems - 1;
  229.         
  230.             HUnlock(fDataHandle);
  231.             
  232.             ShrinkDataHandle(1);
  233.         }
  234.     }
  235. }
  236.  
  237.  
  238.  
  239.  
  240. long TListOfLongs::GetElement(long index)
  241. {
  242.     long     numElems = fNumItems;
  243.     
  244.     if ((numElems > 0) && fDataHandle)
  245.     {
  246.         long**     dh = (long**) fDataHandle;
  247.         long    val = 0;
  248.         
  249.         HLock(fDataHandle);    // locks dh
  250.         val = (*dh)[index-1];
  251.         HUnlock(fDataHandle);
  252.         
  253.         return val;
  254.     }
  255.     else
  256.         return 0;
  257. }
  258.  
  259.  
  260. long TListOfLongs::FindElement(long val)
  261. {
  262.     long     numElems = fNumItems;
  263.     
  264.     if ((numElems > 0) && fDataHandle)
  265.     {
  266.         long**     dh = (long**) fDataHandle;
  267.         long     currentIndex = 0;
  268.         long     currentVal = 0;
  269.         long     lowBound = 1;
  270.         long     highBound = numElems;
  271.         Boolean    found = false;
  272.         
  273.         HLock(fDataHandle);    // locks dh
  274.         
  275.         do
  276.         {
  277.             currentIndex = (lowBound + highBound) >> 1;      // == divide by 2
  278.             currentVal = (*dh)[currentIndex-1];
  279.             if (val < currentVal)
  280.                 highBound = currentIndex-1;
  281.             else
  282.                 lowBound = currentIndex+1;
  283.             found = (val == currentVal);
  284.         } while (!(found || (lowBound > highBound)));
  285.         
  286.         if (!found)
  287.             currentIndex = 0;
  288.             
  289.         HUnlock(fDataHandle);
  290.         
  291.         return currentIndex;
  292.     }
  293.     else
  294.         return 0;
  295. }
  296.  
  297.  
  298.  
  299. /*******************************************************************************
  300. ** TOrderedListOfLongs: Constructor/Destructor
  301. ********************************************************************************/
  302.  
  303. TOrderedListOfLongs::TOrderedListOfLongs()
  304. {
  305. }
  306.  
  307.  
  308. TOrderedListOfLongs::TOrderedListOfLongs(const TOrderedListOfLongs& oldObj)
  309. {
  310.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  311. }
  312.  
  313.  
  314. TOrderedListOfLongs::~TOrderedListOfLongs(void)
  315. {
  316. }
  317.  
  318.  
  319. TOrderedListOfLongs& TOrderedListOfLongs::operator=(const TOrderedListOfLongs& oldObj)
  320. {
  321.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  322.     return *this;
  323. }
  324.  
  325.  
  326. // the business
  327.  
  328.  
  329. OSErr TOrderedListOfLongs::InsertElement(long val)
  330. {
  331.     return -1;
  332. }
  333.  
  334.  
  335. OSErr TOrderedListOfLongs::InsertElementAt(long val, long index)
  336. {
  337.     OSErr err = noErr;
  338.     
  339.     if (!FindElement(val))    // if it's already there, do nothing
  340.     {
  341.         long     lastItem = fNumItems;    
  342.         long**     dh = (long**) fDataHandle;
  343.         
  344.         err = ExpandDataHandle(1);    // grows dh, if more room is needed
  345.             
  346.         HLock(fDataHandle);        // locks dh
  347.         
  348.         if (index <= 1)
  349.             index = 1;
  350.         while (lastItem >= index)
  351.         {
  352.             (*dh)[lastItem] = (*dh)[lastItem-1]; // because array is indexed from 0
  353.             lastItem--;
  354.         }
  355.         (*dh)[lastItem] = val;
  356.         fNumItems = fNumItems + 1;
  357.         
  358.         HUnlock(fDataHandle);
  359.     }
  360.     
  361.     return err;
  362. }
  363.  
  364.  
  365. long TOrderedListOfLongs::FindElement(long val)
  366. {
  367.     long     numElems = fNumItems;
  368.     
  369.     if ((numElems > 0) && fDataHandle)
  370.     {
  371.         long**     dh = (long**) fDataHandle;
  372.         long     currentIndex = numElems;
  373.         long     currentVal;
  374.         Boolean    found = false;
  375.         
  376.         HLock(fDataHandle);    // locks dh
  377.         
  378.         do
  379.         {
  380.             currentVal = (*dh)[currentIndex-1];
  381.             found = (val == currentVal);
  382.             if (!found)
  383.                 currentIndex--;
  384.         } while (!found && currentIndex > 0);
  385.         
  386.         if (!found)
  387.             currentIndex = 0;
  388.             
  389.         HUnlock(fDataHandle);
  390.         
  391.         return currentIndex;
  392.     }
  393.     else
  394.         return 0;
  395. }
  396.  
  397.  
  398.  
  399. /*******************************************************************************
  400. ** TStackOfLongs: Constructor/Destructor
  401. ********************************************************************************/
  402.  
  403. TStackOfLongs::TStackOfLongs()
  404. {
  405. }
  406.  
  407.  
  408. TStackOfLongs::TStackOfLongs(const TStackOfLongs& oldObj)
  409. {
  410.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  411. }
  412.  
  413.  
  414. TStackOfLongs::~TStackOfLongs(void)
  415. {
  416. }
  417.  
  418.  
  419. TStackOfLongs& TStackOfLongs::operator=(const TStackOfLongs& oldObj)
  420. {
  421.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  422.     return *this;
  423. }
  424.  
  425.  
  426. // the business
  427.  
  428.  
  429. OSErr TStackOfLongs::InsertElement(long val)
  430. {
  431.     return -1;
  432. }
  433.  
  434.  
  435. long TStackOfLongs::FindElement(long val)
  436. {
  437.     return -1;
  438. }
  439.  
  440.  
  441.  
  442. OSErr TStackOfLongs::PushElement(long val)
  443. {
  444.     OSErr     err = noErr;
  445.     long     lastItem = fNumItems;    
  446.     long**     dh = (long**) fDataHandle;
  447.     
  448.     err = ExpandDataHandle(1);    // grows dh, if more room is needed
  449.         
  450.     HLock(fDataHandle);        // locks dh
  451.     (*dh)[lastItem] = val;
  452.     fNumItems = fNumItems + 1;
  453.     HUnlock(fDataHandle);
  454.     
  455.     return err;
  456. }
  457.  
  458.  
  459. OSErr TStackOfLongs::PopElement(long *val)
  460. {
  461.     OSErr     err = noErr;
  462.     long    lastItem = fNumItems;    
  463.     long**     dh = (long**) fDataHandle;
  464.     
  465.     HLock(fDataHandle);        // locks dh
  466.     if (lastItem > 0)
  467.         *val = (*dh)[lastItem-1];
  468.     else
  469.         err = -1;
  470.     fNumItems = fNumItems - 1;
  471.     HUnlock(fDataHandle);
  472.     
  473.     if (!err)
  474.         err = ShrinkDataHandle(1);
  475.         
  476.     return err;
  477. }
  478.